package com.utils.basejava.NIO;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 一、使用NIO完成网络通信的三个核心：
 * 
 * 1、通道(Channel):负责连接
 * java.nio.channels.Channel 接口：
 * 			|--SelectableChannel
 * 				|--SocketChannel
 * 				|--ServerSocketChannel
 * 				|--DatagramChannel
 * 
 * 				|--Pipe.SinkChannel
 * 				|--Pipe.SourceChannel 
 * 
 * 2、缓冲区（Buffer）：负责数据的存取
 * 
 * 3、选择器（Selector）:是SelectableChannel的多路复用器。用于监控SelectableChannel 的IO状况
 *
 * @author XR-8
 *
 */
public class TestBlockingNIO {
	
	//客户端
	
	public void client() throws IOException {
		//1、获取通道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8998));
		
		FileChannel fc = FileChannel.open(Paths.get("C:\\Users\\XR-8\\Desktop\\忧伤.jpg"), StandardOpenOption.READ);
		//2、分配指定大小的缓冲区
		ByteBuffer bb = ByteBuffer.allocate(1024);
		//3、读取本地文件，并发送到服务端
		while(fc.read(bb)!=-1){
			bb.flip();
			sChannel.write(bb);
			bb.clear();
		}
		
		//4、关闭通道
		fc.close();
		sChannel.close();
	}
	
	//服务端
	
	public void server() throws IOException {
		//1、获取通道
		ServerSocketChannel ssc = ServerSocketChannel.open();
		
		FileChannel fc = FileChannel.open(Paths.get("BlockNIO.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
		//2、绑定连接
		ssc.bind(new InetSocketAddress(8998));
		
		//3、获取客户端连接的通道
		SocketChannel accept = ssc.accept();
		
		//4、分配指定大小的缓冲区
		ByteBuffer bb = ByteBuffer.allocate(1024);
		
		//5、接收客户端的数据，并保存到本地
		while(accept.read(bb)!=-1) {
			bb.flip();
			fc.write(bb);
			bb.clear();
		}
		
		//6、关闭通道
		fc.close();
		accept.close();
		ssc.close();
	}
	

}
